Interactive Data Visualization Frameworks

There are various ways to create interactive visualizations. We present two very popular packages, that adapt ggplots syntax, making them very comfortable to use.

Plots

plotly

Ther are two ways to make use of plotlys framework.

ggplotly & plotly for R ggplotly turns your ggplot graphs with the function ggplotly() into an interactive graph.

plotly uses a different syntax style, but provides more interactive capabilities

library(plotly)
library(broom)
library(dplyr)
data(diamonds, package = "ggplot2")

data <- sample_n(diamonds, 300)

modlss <- loess(price ~ carat, data = data)
fit <- arrange(augment(modlss,se_fit = TRUE), carat)

p <- ggplot(NULL, mapping = aes(x = carat, y = price )) +
              geom_ribbon(data  = fit, mapping = aes(ymin = .fitted - 2*.se.fit, ymax = .fitted + 2*.se.fit), fill = "grey70")+
              geom_point(data = data, alpha = 0.7, mapping = aes(size = depth, group = cut, color = cut)) +
              geom_line(data = fit, aes(x = carat, y = .fitted)) 
  


ggplotly(p) %>%
  layout(legend = list(x = 0.1, y = 0.9))

highcharter

The main difference in ggplot2’s geom_ functions and hc_add_series is that we need to add data and aesthetics explicitly in every function while in ggplot2 one can add data and aesthetics in a layer and then can further add more geoms which can work on same data and aesthetics.

An accurate example is given below using the diamond dataset in the ggplot2 package.

library(highcharter)
library(broom)
library(dplyr)
data(diamonds, package = "ggplot2")

data <- sample_n(diamonds, 300)

modlss <- loess(price ~ carat, data = data)
fit <- arrange(augment(modlss,se_fit = TRUE), carat)

highchart() %>%
  hc_plotOptions(bubble = list(minSize = 1, maxSize = 20)) %>% hc_add_series(fit, type = "arearange",
                hcaes(x = carat, low = .fitted - 2*.se.fit,
                      high = .fitted + 2*.se.fit),
                linkedTo = "fit") %>%
  hc_add_series(data, type = "scatter",
                hcaes(x = carat, y = price, size = depth, group = cut)) %>%
  hc_add_series(fit, type = "line", hcaes(x = carat, y = .fitted),
                name = "Fit", id = "fit")

plot_ly

The main difference in ggplot2’s geom_ functions and hc_add_series is that we need to add data and aesthetics explicitly in every function while in ggplot2 one can add data and aesthetics in a layer and then can further add more geoms which can work on same data and aesthetics.

An accurate example is given below using the diamond dataset in the ggplot2 package.

library(plotly)
library(broom)
library(dplyr)
library(shiny)
data(diamonds, package = "ggplot2")

data <- sample_n(diamonds, 300)

modlss <- loess(price ~ carat, data = data)
fit <- augment(modlss, se_fit = TRUE)


plot_ly(data = data, x = ~carat, width = 700,
    height = 500) %>% 
  add_markers(y = ~price, 
              color = ~cut, 
              size = ~carat, 
              text = ~paste("Price: ", price, '$<br>Cut:', cut)) %>%
  add_lines(y = ~fitted(loess(price ~ carat)),
                         line = list(color = 'lightblue'),
                         name = "Loess Smoother") %>%
  add_ribbons(data = augment(loess(price ~ carat,data = data),se_fit = TRUE), 
              ymin = ~.fitted - 2 * .se.fit,
              ymax = ~.fitted + 2 * .se.fit,
              line = list(color = "rgba(2, 162, 182, 0.05)"),
              fillcolor = "rgba(2, 162, 182, 0.2)",
              name = "Standarderror"
              ) %>%
  layout(legend = list(x = 0.1, y = 0.9))

Maps

The leaflet package is a very popular framework to create interactive maps.

library(leaflet)
## Warning: package 'leaflet' was built under R version 4.1.3
leaflet() %>%
  setView(lng= 5.94852, lat= 49.50437, zoom = 16) %>% 
  addTiles() %>%
  addMarkers(lng= 5.94852, lat= 49.50437,  popup = "Interactive Data Viz Course") 

Data tables

library(DT)
## Warning: package 'DT' was built under R version 4.1.3
## 
## Attaching package: 'DT'
## The following objects are masked from 'package:shiny':
## 
##     dataTableOutput, renderDataTable
data(diamonds, package = "ggplot2") # load data 

data <- diamonds[sample(nrow(diamonds), 300),1:5] #create a subset of the dataset

datatable(data, filter = 'top',  
          options = list(   searchHighlight = TRUE, pageLength = 15 ))

Slides

Using ioslides we can also implement interactive plots in our presentations!

---
title: Do Natural Disasters Stimulate Environmental Attitudes? Evidence from a Natural
  Experiment.
author: "Hamid Bulut"
date: "27/4/2022"
output:
  ioslides_presentation:
    css: www/styles.css
    widescreen: yes
    smaller: yes
    highlight: monochrome
  slidy_presentation:
    highlight: monochrome
  beamer_presentation:
    highlight: monochrome
subtitle: A Regression Discontinuity Design Analysis
editor_options:
  markdown:
    wrap: 72
---

Publish R Markdown documents on RPubs

https://rpubs.com/

LS0tDQp0aXRsZTogIkludGVyYWN0aXZpdHkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4gDQogICAgI251bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jX2RlcHRoOiAyDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgI2Nzczogc2xpZGVzL3d3dy9zdHlsZS5jc3MNCiAgaHRtbF9ub3RlYm9vazoNCiAgIHRvYzogeWVzDQogICB0aGVtZTogbHVtZW4gDQogICAjbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgdG9jX2RlcHRoOiAzDQogICB0b2NfZmxvYXQ6IHllcw0KZWRpdG9yX29wdGlvbnM6DQogIG1hcmtkb3duOg0KICAgIHdyYXA6IDE0MA0KLS0tDQoNCg0KIyBJbnRlcmFjdGl2ZSBEYXRhIFZpc3VhbGl6YXRpb24gRnJhbWV3b3Jrcw0KVGhlcmUgYXJlIHZhcmlvdXMgd2F5cyB0byBjcmVhdGUgaW50ZXJhY3RpdmUgdmlzdWFsaXphdGlvbnMuIFdlIHByZXNlbnQgdHdvIHZlcnkgcG9wdWxhciBwYWNrYWdlcywgdGhhdCBhZGFwdCBnZ3Bsb3RzIHN5bnRheCwgbWFraW5nIHRoZW0gdmVyeSBjb21mb3J0YWJsZSB0byB1c2UuIA0KDQojIyBQbG90cyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KIyMjIHBsb3RseQ0KDQpUaGVyIGFyZSB0d28gd2F5cyB0byBtYWtlIHVzZSBvZiBwbG90bHlzIGZyYW1ld29yay4gIA0KDQpbZ2dwbG90bHldKGh0dHBzOi8vcGxvdGx5LmNvbS9nZ3Bsb3QyLykgJiBbcGxvdGx5IGZvciBSXShodHRwczovL3Bsb3RseS5jb20vci8pDQpnZ3Bsb3RseSB0dXJucyB5b3VyIGdncGxvdCBncmFwaHMgd2l0aCB0aGUgZnVuY3Rpb24gKmdncGxvdGx5KCkqIGludG8gYW4gaW50ZXJhY3RpdmUgZ3JhcGguIA0KDQpwbG90bHkgdXNlcyBhIGRpZmZlcmVudCBzeW50YXggc3R5bGUsIGJ1dCBwcm92aWRlcyBtb3JlIGludGVyYWN0aXZlIGNhcGFiaWxpdGllcw0KDQpgYGB7ciBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHNpemU9ICIxMDAlIn0NCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkoZHBseXIpDQpkYXRhKGRpYW1vbmRzLCBwYWNrYWdlID0gImdncGxvdDIiKQ0KDQpkYXRhIDwtIHNhbXBsZV9uKGRpYW1vbmRzLCAzMDApDQoNCm1vZGxzcyA8LSBsb2VzcyhwcmljZSB+IGNhcmF0LCBkYXRhID0gZGF0YSkNCmZpdCA8LSBhcnJhbmdlKGF1Z21lbnQobW9kbHNzLHNlX2ZpdCA9IFRSVUUpLCBjYXJhdCkNCg0KcCA8LSBnZ3Bsb3QoTlVMTCwgbWFwcGluZyA9IGFlcyh4ID0gY2FyYXQsIHkgPSBwcmljZSApKSArDQogICAgICAgICAgICAgIGdlb21fcmliYm9uKGRhdGEgID0gZml0LCBtYXBwaW5nID0gYWVzKHltaW4gPSAuZml0dGVkIC0gMiouc2UuZml0LCB5bWF4ID0gLmZpdHRlZCArIDIqLnNlLmZpdCksIGZpbGwgPSAiZ3JleTcwIikrDQogICAgICAgICAgICAgIGdlb21fcG9pbnQoZGF0YSA9IGRhdGEsIGFscGhhID0gMC43LCBtYXBwaW5nID0gYWVzKHNpemUgPSBkZXB0aCwgZ3JvdXAgPSBjdXQsIGNvbG9yID0gY3V0KSkgKw0KICAgICAgICAgICAgICBnZW9tX2xpbmUoZGF0YSA9IGZpdCwgYWVzKHggPSBjYXJhdCwgeSA9IC5maXR0ZWQpKSANCiAgDQoNCg0KZ2dwbG90bHkocCkgJT4lDQogIGxheW91dChsZWdlbmQgPSBsaXN0KHggPSAwLjEsIHkgPSAwLjkpKQ0KYGBgDQoNCiANCiMjIyBoaWdoY2hhcnRlciANCg0KVGhlIG1haW4gZGlmZmVyZW5jZSBpbiBnZ3Bsb3QyJ3MgZ2VvbV8gZnVuY3Rpb25zIGFuZCBoY19hZGRfc2VyaWVzIGlzIHRoYXQgd2UgbmVlZCB0byBhZGQgZGF0YSBhbmQgYWVzdGhldGljcyBleHBsaWNpdGx5IGluIGV2ZXJ5IGZ1bmN0aW9uIHdoaWxlIGluIGdncGxvdDIgb25lIGNhbiBhZGQgZGF0YSBhbmQgYWVzdGhldGljcyBpbiBhIGxheWVyIGFuZCB0aGVuIGNhbiBmdXJ0aGVyIGFkZCBtb3JlIGdlb21zIHdoaWNoIGNhbiB3b3JrIG9uIHNhbWUgZGF0YSBhbmQgYWVzdGhldGljcy4NCg0KQW4gYWNjdXJhdGUgZXhhbXBsZSBpcyBnaXZlbiBiZWxvdyB1c2luZyB0aGUgZGlhbW9uZCBkYXRhc2V0IGluIHRoZSBnZ3Bsb3QyIHBhY2thZ2UuDQoNCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9DQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkoZHBseXIpDQpkYXRhKGRpYW1vbmRzLCBwYWNrYWdlID0gImdncGxvdDIiKQ0KDQpkYXRhIDwtIHNhbXBsZV9uKGRpYW1vbmRzLCAzMDApDQoNCm1vZGxzcyA8LSBsb2VzcyhwcmljZSB+IGNhcmF0LCBkYXRhID0gZGF0YSkNCmZpdCA8LSBhcnJhbmdlKGF1Z21lbnQobW9kbHNzLHNlX2ZpdCA9IFRSVUUpLCBjYXJhdCkNCg0KaGlnaGNoYXJ0KCkgJT4lDQogIGhjX3Bsb3RPcHRpb25zKGJ1YmJsZSA9IGxpc3QobWluU2l6ZSA9IDEsIG1heFNpemUgPSAyMCkpICU+JSBoY19hZGRfc2VyaWVzKGZpdCwgdHlwZSA9ICJhcmVhcmFuZ2UiLA0KICAgICAgICAgICAgICAgIGhjYWVzKHggPSBjYXJhdCwgbG93ID0gLmZpdHRlZCAtIDIqLnNlLmZpdCwNCiAgICAgICAgICAgICAgICAgICAgICBoaWdoID0gLmZpdHRlZCArIDIqLnNlLmZpdCksDQogICAgICAgICAgICAgICAgbGlua2VkVG8gPSAiZml0IikgJT4lDQogIGhjX2FkZF9zZXJpZXMoZGF0YSwgdHlwZSA9ICJzY2F0dGVyIiwNCiAgICAgICAgICAgICAgICBoY2Flcyh4ID0gY2FyYXQsIHkgPSBwcmljZSwgc2l6ZSA9IGRlcHRoLCBncm91cCA9IGN1dCkpICU+JQ0KICBoY19hZGRfc2VyaWVzKGZpdCwgdHlwZSA9ICJsaW5lIiwgaGNhZXMoeCA9IGNhcmF0LCB5ID0gLmZpdHRlZCksDQogICAgICAgICAgICAgICAgbmFtZSA9ICJGaXQiLCBpZCA9ICJmaXQiKQ0KIA0KYGBgDQoNCiMjIyBwbG90X2x5IA0KDQpUaGUgbWFpbiBkaWZmZXJlbmNlIGluIGdncGxvdDIncyBnZW9tXyBmdW5jdGlvbnMgYW5kIGhjX2FkZF9zZXJpZXMgaXMgdGhhdCB3ZSBuZWVkIHRvIGFkZCBkYXRhIGFuZCBhZXN0aGV0aWNzIGV4cGxpY2l0bHkgaW4gZXZlcnkgZnVuY3Rpb24gd2hpbGUgaW4gZ2dwbG90MiBvbmUgY2FuIGFkZCBkYXRhIGFuZCBhZXN0aGV0aWNzIGluIGEgbGF5ZXIgYW5kIHRoZW4gY2FuIGZ1cnRoZXIgYWRkIG1vcmUgZ2VvbXMgd2hpY2ggY2FuIHdvcmsgb24gc2FtZSBkYXRhIGFuZCBhZXN0aGV0aWNzLg0KDQpBbiBhY2N1cmF0ZSBleGFtcGxlIGlzIGdpdmVuIGJlbG93IHVzaW5nIHRoZSBkaWFtb25kIGRhdGFzZXQgaW4gdGhlIGdncGxvdDIgcGFja2FnZS4NCg0KYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBvdXQud2lkdGg9IjEwMCUiLCBmaWcuYWxpZ249J2NlbnRlcid9DQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzaGlueSkNCmRhdGEoZGlhbW9uZHMsIHBhY2thZ2UgPSAiZ2dwbG90MiIpDQoNCmRhdGEgPC0gc2FtcGxlX24oZGlhbW9uZHMsIDMwMCkNCg0KbW9kbHNzIDwtIGxvZXNzKHByaWNlIH4gY2FyYXQsIGRhdGEgPSBkYXRhKQ0KZml0IDwtIGF1Z21lbnQobW9kbHNzLCBzZV9maXQgPSBUUlVFKQ0KDQoNCnBsb3RfbHkoZGF0YSA9IGRhdGEsIHggPSB+Y2FyYXQsIHdpZHRoID0gNzAwLA0KICAgIGhlaWdodCA9IDUwMCkgJT4lIA0KICBhZGRfbWFya2Vycyh5ID0gfnByaWNlLCANCiAgICAgICAgICAgICAgY29sb3IgPSB+Y3V0LCANCiAgICAgICAgICAgICAgc2l6ZSA9IH5jYXJhdCwgDQogICAgICAgICAgICAgIHRleHQgPSB+cGFzdGUoIlByaWNlOiAiLCBwcmljZSwgJyQ8YnI+Q3V0OicsIGN1dCkpICU+JQ0KICBhZGRfbGluZXMoeSA9IH5maXR0ZWQobG9lc3MocHJpY2UgfiBjYXJhdCkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJ2xpZ2h0Ymx1ZScpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiTG9lc3MgU21vb3RoZXIiKSAlPiUNCiAgYWRkX3JpYmJvbnMoZGF0YSA9IGF1Z21lbnQobG9lc3MocHJpY2UgfiBjYXJhdCxkYXRhID0gZGF0YSksc2VfZml0ID0gVFJVRSksIA0KICAgICAgICAgICAgICB5bWluID0gfi5maXR0ZWQgLSAyICogLnNlLmZpdCwNCiAgICAgICAgICAgICAgeW1heCA9IH4uZml0dGVkICsgMiAqIC5zZS5maXQsDQogICAgICAgICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gInJnYmEoMiwgMTYyLCAxODIsIDAuMDUpIiksDQogICAgICAgICAgICAgIGZpbGxjb2xvciA9ICJyZ2JhKDIsIDE2MiwgMTgyLCAwLjIpIiwNCiAgICAgICAgICAgICAgbmFtZSA9ICJTdGFuZGFyZGVycm9yIg0KICAgICAgICAgICAgICApICU+JQ0KICBsYXlvdXQobGVnZW5kID0gbGlzdCh4ID0gMC4xLCB5ID0gMC45KSkNCg0KYGBgDQoNCiMjIE1hcHMNCg0KVGhlIFtsZWFmbGV0XShodHRwczovL3JzdHVkaW8uZ2l0aHViLmlvL2xlYWZsZXQvKSBwYWNrYWdlIGlzIGEgdmVyeSBwb3B1bGFyIGZyYW1ld29yayB0byBjcmVhdGUgaW50ZXJhY3RpdmUgbWFwcy4gIA0KDQpgYGB7cn0NCmxpYnJhcnkobGVhZmxldCkNCmxlYWZsZXQoKSAlPiUNCiAgc2V0Vmlldyhsbmc9IDUuOTQ4NTIsIGxhdD0gNDkuNTA0MzcsIHpvb20gPSAxNikgJT4lIA0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRNYXJrZXJzKGxuZz0gNS45NDg1MiwgbGF0PSA0OS41MDQzNywgIHBvcHVwID0gIkludGVyYWN0aXZlIERhdGEgVml6IENvdXJzZSIpIA0KYGBgDQoNCg0KDQojIyBEYXRhIHRhYmxlcw0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KERUKQ0KZGF0YShkaWFtb25kcywgcGFja2FnZSA9ICJnZ3Bsb3QyIikgIyBsb2FkIGRhdGEgDQoNCmRhdGEgPC0gZGlhbW9uZHNbc2FtcGxlKG5yb3coZGlhbW9uZHMpLCAzMDApLDE6NV0gI2NyZWF0ZSBhIHN1YnNldCBvZiB0aGUgZGF0YXNldA0KDQpkYXRhdGFibGUoZGF0YSwgZmlsdGVyID0gJ3RvcCcsICANCiAgICAgICAgICBvcHRpb25zID0gbGlzdCggICBzZWFyY2hIaWdobGlnaHQgPSBUUlVFLCBwYWdlTGVuZ3RoID0gMTUgKSkNCg0KYGBgDQojIyBTbGlkZXMgDQoNClVzaW5nIGlvc2xpZGVzIHdlIGNhbiBhbHNvIGltcGxlbWVudCBpbnRlcmFjdGl2ZSBwbG90cyBpbiBvdXIgcHJlc2VudGF0aW9ucyEgDQoNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCi0tLQ0KdGl0bGU6IERvIE5hdHVyYWwgRGlzYXN0ZXJzIFN0aW11bGF0ZSBFbnZpcm9ubWVudGFsIEF0dGl0dWRlcz8gRXZpZGVuY2UgZnJvbSBhIE5hdHVyYWwNCiAgRXhwZXJpbWVudC4NCmF1dGhvcjogIkhhbWlkIEJ1bHV0Ig0KZGF0ZTogIjI3LzQvMjAyMiINCm91dHB1dDoNCiAgaW9zbGlkZXNfcHJlc2VudGF0aW9uOg0KICAgIGNzczogd3d3L3N0eWxlcy5jc3MNCiAgICB3aWRlc2NyZWVuOiB5ZXMNCiAgICBzbWFsbGVyOiB5ZXMNCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUNCiAgc2xpZHlfcHJlc2VudGF0aW9uOg0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICBiZWFtZXJfcHJlc2VudGF0aW9uOg0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0Kc3VidGl0bGU6IEEgUmVncmVzc2lvbiBEaXNjb250aW51aXR5IERlc2lnbiBBbmFseXNpcw0KZWRpdG9yX29wdGlvbnM6DQogIG1hcmtkb3duOg0KICAgIHdyYXA6IDcyDQotLS0NCmBgYA0KDQoNCg0KDQojIFB1Ymxpc2ggUiBNYXJrZG93biBkb2N1bWVudHMgb24gUlB1YnMNCg0KaHR0cHM6Ly9ycHVicy5jb20vDQoNCiMgUiBNYXJrZG93biBTeW50YXgNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duL21hcmtkb3duLXN5bnRheC5odG1sDQoNCg0KIyBTaGlueQ0KDQpodHRwczovL3JwdWJzLmNvbS9vZGVuaXBpbmVkby9idWlsZGluZy13ZWItYXBwbGljYXRpb25zLXdpdGgtU2hpbnktaW4tUg0KDQoNCg==